﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AutoMapper;
using System.ComponentModel.Composition;
using System.IO;
using System.Data;
using System.Diagnostics.CodeAnalysis;

namespace Steve.EFDataLayer
{
    [Export(typeof(SiteExplorerRepository))]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public class EFSiteExplorerRepository : SiteExplorerRepository
    {
        static EFSiteExplorerRepository()
        {
            SteveEFDataLayer.SetupAutoMapper();
        }

        protected override IEnumerable<Site> GetSitesCore()
        {
            using (var ctx = new SteveEntities())
            {
                var query = from s in ctx.DbSites
                            select s;

                return query.ToList().Select(s => Mapper.Map<DbSite, Site>(s));
            }
        }

        protected override Site SaveSiteCore(Site toSave)
        {
            using (var ctx = new SteveEntities())
            {
                var existing = (from s in ctx.DbSites
                                where s.SiteName == toSave.SiteName
                                select s).FirstOrDefault();

                if (existing == null)
                {
                    existing = new DbSite();
                    ctx.AddToDbSites(existing);
                }   

                Mapper.Map(toSave, existing);

                ctx.SaveChanges();

                return Mapper.Map<DbSite, Site>(existing);
            }
        }

        public override SiteUrl GetSiteUrl(Guid id)
        {
            using (var ctx = new SteveEntities())
            {
                var query = from u in ctx.DbSiteUrls
                            where u.Id == id
                            select u;

                var result = query.FirstOrDefault();

                if (result == null) return null;

                return Mapper.Map<DbSiteUrl, SiteUrl>(result);
            }
        }

        protected override SiteUrl SaveSiteUrlCore(SiteUrl toSave)
        {
            using (var ctx = new SteveEntities())
            {
                var existing = (from u in ctx.DbSiteUrls
                                where u.Id == toSave.Id
                                select u).FirstOrDefault();

                if (existing == null)
                {
                    existing = new DbSiteUrl();
                    ctx.AddToDbSiteUrls(existing);
                }

                Mapper.Map(toSave, existing);

                ctx.SaveChanges();

                return Mapper.Map<DbSiteUrl, SiteUrl>(existing);
            }
        }

        protected override RewriteUrl SaveUrlRewriteCore(RewriteUrl toSave)
        {
            using (var ctx = new SteveEntities())
            {
                var existing = (from u in ctx.DbUrlRewrites
                                where u.Id == toSave.Id
                                select u).FirstOrDefault();

                if (existing == null)
                {
                    existing = new DbUrlRewrite();
                    ctx.AddToDbUrlRewrites(existing);
                }

                Mapper.Map(toSave, existing);

                ctx.SaveChanges();

                return Mapper.Map<DbUrlRewrite, RewriteUrl>(existing);
            }
        }

        public override RewriteUrl GetRewriteUrl(Guid id)
        {
            using (var ctx = new SteveEntities())
            {
                var query = from r in ctx.DbUrlRewrites
                            where r.Id == id
                            select r;

                var result = query.FirstOrDefault();

                if (result == null) return null;

                return Mapper.Map<DbUrlRewrite, RewriteUrl>(result);
            }
        }

        public override IEnumerable<SiteUrl> GetSiteUrls(string siteName, DateTime? liveUntil)
        {
            using (var ctx = new SteveEntities())
            {
                var query = from u in ctx.DbSiteUrls
                            where u.SiteName == siteName
                            select u;

                if (liveUntil != null)
                {
                    query = from u in query
                            where (u.StartDate == null || u.StartDate <= liveUntil)
                            && (u.EndDate == null || u.EndDate >= liveUntil)
                            select u;
                }

                return query.ToList().Select(u => Mapper.Map<DbSiteUrl, SiteUrl>(u));
            }
        }

        public override IEnumerable<RewriteUrl> GetRewrites(string siteName, DateTime? liveUntil)
        {
            using (var ctx = new SteveEntities())
            {
                var query = from r in ctx.DbUrlRewrites
                            where r.SiteName == siteName
                            select r;

                if (liveUntil != null)
                {
                    query = from r in query
                            where (r.StartDate == null || r.StartDate <= liveUntil)
                            && (r.EndDate == null || r.EndDate >= liveUntil)
                            select r;
                }

                return query.ToList().Select(r => Mapper.Map<DbUrlRewrite, RewriteUrl>(r));
            }
        }

        public override IEnumerable<RewriteUrl> GetRewritesForSiteUrl(Guid siteUrlId)
        {
            using (var ctx = new SteveEntities())
            {
                var query = from r in ctx.DbUrlRewrites
                            where r.SiteUrlId == siteUrlId
                            select r;

                return query.ToList().Select(r => Mapper.Map<DbUrlRewrite, RewriteUrl>(r));
            }
        }

    }
}
